home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_perl.idb / usr / freeware / catman / u_man / cat1 / perlsec.Z / perlsec
Encoding:
Text File  |  1998-10-28  |  22.0 KB  |  529 lines

  1.  
  2.  
  3.  
  4.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  5.  
  6.  
  7.  
  8.      NNNNAAAAMMMMEEEE
  9.       perlsec - Perl security
  10.  
  11.      DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  12.       Perl is designed to make it easy to program securely even
  13.       when running with extra privileges, like setuid or setgid
  14.       programs.  Unlike most command line shells, which are    based
  15.       on multiple substitution passes on each line of the script,
  16.       Perl uses a more conventional    evaluation scheme with fewer
  17.       hidden snags.     Additionally, because the language has    more
  18.       builtin functionality, it can    rely less upon external    (and
  19.       possibly untrustworthy) programs to accomplish its purposes.
  20.  
  21.       Perl automatically enables a set of special security checks,
  22.       called _t_a_i_n_t _m_o_d_e, when it detects its program running with
  23.       differing real and effective user or group IDs.  The setuid
  24.       bit in Unix permissions is mode 04000, the setgid bit    mode
  25.       02000; either    or both    may be set.  You can also enable taint
  26.       mode explicitly by using the ----TTTT command line flag. This flag
  27.       is _s_t_r_o_n_g_l_y suggested    for server programs and    any program
  28.       run on behalf    of someone else, such as a CGI script. Once
  29.       taint    mode is    on, it's on for    the remainder of your script.
  30.  
  31.       While    in this    mode, Perl takes special precautions called
  32.       _t_a_i_n_t    _c_h_e_c_k_s to prevent both obvious and subtle traps.  Some
  33.       of these checks are reasonably simple, such as verifying
  34.       that path directories    aren't writable    by others; careful
  35.       programmers have always used checks like these.  Other
  36.       checks, however, are best supported by the language itself,
  37.       and it is these checks especially that contribute to making
  38.       a set-id Perl    program    more secure than the corresponding C
  39.       program.
  40.  
  41.       You may not use data derived from outside your program to
  42.       affect something else    outside    your program--at least,    not by
  43.       accident.  All command line arguments, environment
  44.       variables, locale information    (see the _p_e_r_l_l_o_c_a_l_e manpage),
  45.       results of certain system calls (readdir, readlink, the
  46.       gecos    field of getpw*    calls),    and all    file input are marked
  47.       as "tainted".     Tainted data may not be used directly or
  48.       indirectly in    any command that invokes a sub-shell, nor in
  49.       any command that modifies files, directories,    or processes.
  50.       (IIIImmmmppppoooorrrrttttaaaannnntttt eeeexxxxcccceeeeppppttttiiiioooonnnn:    If you pass a list of arguments    to
  51.       either system    or exec, the elements of that list are NNNNOOOOTTTT
  52.       checked for taintedness.) Any    variable set to    a value
  53.       derived from tainted data will itself    be tainted, even if it
  54.       is logically impossible for the tainted data to alter    the
  55.       variable.  Because taintedness is associated with each
  56.       scalar value,    some elements of an array can be tainted and
  57.       others not.
  58.  
  59.       For example:
  60.  
  61.  
  62.  
  63.      Page 1                        (printed 10/23/98)
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  71.  
  72.  
  73.  
  74.           $arg = shift;          # $arg is tainted
  75.           $hid = $arg, 'bar';      # $hid is also tainted
  76.           $line = <>;          # Tainted
  77.           $line = <STDIN>;          # Also tainted
  78.           open FOO,    "/home/me/bar" or die $!;
  79.           $line = <FOO>;          # Still tainted
  80.           $path = $ENV{'PATH'};      # Tainted, but see below
  81.           $data = 'abc';          # Not    tainted
  82.  
  83.           system "echo $arg";      # Insecure
  84.           system "/bin/echo", $arg;      # Secure (doesn't use    sh)
  85.           system "echo $hid";      # Insecure
  86.           system "echo $data";      # Insecure until PATH    set
  87.  
  88.           $path = $ENV{'PATH'};      # $path now tainted
  89.  
  90.           $ENV{'PATH'} = '/bin:/usr/bin';
  91.           delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
  92.  
  93.           $path = $ENV{'PATH'};      # $path now NOT tainted
  94.           system "echo $data";      # Is secure now!
  95.  
  96.           open(FOO,    "< $arg");      # OK - read-only file
  97.           open(FOO,    "> $arg");      # Not    OK - trying to write
  98.  
  99.           open(FOO,"echo $arg|");      # Not    OK, but...
  100.           open(FOO,"-|")
  101.           or exec 'echo', $arg;      # OK
  102.  
  103.           $shout = `echo $arg`;      # Insecure, $shout now tainted
  104.  
  105.           unlink $data, $arg;      # Insecure
  106.           umask $arg;          # Insecure
  107.  
  108.           exec "echo $arg";          # Insecure
  109.           exec "echo", $arg;      # Secure (doesn't use    the shell)
  110.           exec "sh", '-c', $arg;      # Considered secure, alas!
  111.  
  112.           @files = <*.c>;          # Always insecure (uses csh)
  113.           @files = glob('*.c');      # Always insecure (uses csh)
  114.  
  115.       If you try to    do something insecure, you will    get a fatal
  116.       error    saying something like "Insecure    dependency" or
  117.       "Insecure $ENV{PATH}".  Note that you    can still write    an
  118.       insecure ssssyyyysssstttteeeemmmm or eeeexxxxeeeecccc, but only by explicitly doing
  119.       something like the "considered secure" example above.
  120.  
  121.       LLLLaaaauuuunnnnddddeeeerrrriiiinnnngggg aaaannnndddd DDDDeeeetttteeeeccccttttiiiinnnngggg TTTTaaaaiiiinnnntttteeeedddd DDDDaaaattttaaaa
  122.  
  123.       To test whether a variable contains tainted data, and    whose
  124.       use would thus trigger an "Insecure dependency" message,
  125.       check    your nearby CPAN mirror    for the    _T_a_i_n_t._p_m module, which
  126.  
  127.  
  128.  
  129.      Page 2                        (printed 10/23/98)
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  137.  
  138.  
  139.  
  140.       should become    available around November 1997.     Or you    may be
  141.       able to use the following _i_s__t_a_i_n_t_e_d() function.
  142.  
  143.           sub is_tainted {
  144.           return ! eval    {
  145.               join('',@_), kill    0;
  146.               1;
  147.           };
  148.           }
  149.  
  150.       This function    makes use of the fact that the presence    of
  151.       tainted data anywhere    within an expression renders the
  152.       entire expression tainted.  It would be inefficient for
  153.       every    operator to test every argument    for taintedness.
  154.       Instead, the slightly    more efficient and conservative
  155.       approach is used that    if any tainted value has been accessed
  156.       within the same expression, the whole    expression is
  157.       considered tainted.
  158.  
  159.       But testing for taintedness gets you only so far.  Sometimes
  160.       you have just    to clear your data's taintedness.  The only
  161.       way to bypass    the tainting mechanism is by referencing
  162.       subpatterns from a regular expression    match.    Perl presumes
  163.       that if you reference    a substring using $1, $2, etc.,    that
  164.       you knew what    you were doing when you    wrote the pattern.
  165.       That means using a bit of thought--don't just    blindly
  166.       untaint anything, or you defeat the entire mechanism.     It's
  167.       better to verify that    the variable has only good characters
  168.       (for certain values of "good") rather    than checking whether
  169.       it has any bad characters.  That's because it's far too easy
  170.       to miss bad characters that you never    thought    of.
  171.  
  172.       Here's a test    to make    sure that the data contains nothing
  173.       but "word" characters    (alphabetics, numerics,    and
  174.       underscores),    a hyphen, an at    sign, or a dot.
  175.  
  176.           if ($data    =~ /^([-\@\w.]+)$/) {
  177.           $data    = $1;              # $data now untainted
  178.           }    else {
  179.           die "Bad data    in $data";      # log    this somewhere
  180.           }
  181.  
  182.       This is fairly secure    because    /\w+/ doesn't normally match
  183.       shell    metacharacters,    nor are    dot, dash, or at going to mean
  184.       something special to the shell.  Use of /.+/ would have been
  185.       insecure in theory because it    lets everything    through, but
  186.       Perl doesn't check for that.    The lesson is that when
  187.       untainting, you must be exceedingly careful with your
  188.       patterns.  Laundering    data using regular expression is the
  189.       _O_N_L_Y mechanism for untainting    dirty data, unless you use the
  190.       strategy detailed below to fork a child of lesser privilege.
  191.  
  192.  
  193.  
  194.  
  195.      Page 3                        (printed 10/23/98)
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  203.  
  204.  
  205.  
  206.       The example does not untaint $data if    use locale is in
  207.       effect, because the characters matched by \w are determined
  208.       by the locale.  Perl considers that locale definitions are
  209.       untrustworthy    because    they contain data from outside the
  210.       program.  If you are writing a locale-aware program, and
  211.       want to launder data with a regular expression containing
  212.       \w, put no locale ahead of the expression in the same    block.
  213.       See the SECURITY entry in the    _p_e_r_l_l_o_c_a_l_e manpage for further
  214.       discussion and examples.
  215.  
  216.       SSSSwwwwiiiittttcccchhhheeeessss OOOOnnnn tttthhhheeee """"####!!!!"""" LLLLiiiinnnneeee
  217.  
  218.       When you make    a script executable, in    order to make it
  219.       usable as a command, the system will pass switches to    perl
  220.       from the script's #!    line.  Perl checks that    any command
  221.       line switches    given to a setuid (or setgid) script actually
  222.       match    the ones set on    the #! line.  Some Unix    and Unix-like
  223.       environments impose a    one-switch limit on the    #!  line, so
  224.       you may need to use something    like -wU instead of -w -U
  225.       under    such systems.  (This issue should arise    only in    Unix
  226.       or Unix-like environments that support #! and    setuid or
  227.       setgid scripts.)
  228.  
  229.       CCCClllleeeeaaaannnniiiinnnngggg UUUUpppp YYYYoooouuuurrrr PPPPaaaatttthhhh
  230.  
  231.       For "Insecure    $ENV{PATH}" messages, you need to set
  232.       $ENV{'PATH'} to a known value, and each directory in the
  233.       path must be non-writable by others than its owner and
  234.       group.  You may be surprised to get this message even    if the
  235.       pathname to your executable is fully qualified.  This    is _n_o_t
  236.       generated because you    didn't supply a    full path to the
  237.       program; instead, it's generated because you never set your
  238.       PATH environment variable, or    you didn't set it to something
  239.       that was safe.  Because Perl can't guarantee that the
  240.       executable in    question isn't itself going to turn around and
  241.       execute some other program that is dependent on your PATH,
  242.       it makes sure    you set    the PATH.
  243.  
  244.       The PATH isn't the only environment variable which can cause
  245.       problems.  Because some shells may use the variables IFS,
  246.       CDPATH, ENV, and BASH_ENV, Perl checks that those are    either
  247.       empty    or untainted when starting subprocesses. You may wish
  248.       to add something like    this to    your setid and taint-checking
  249.       scripts.
  250.  
  251.           delete @ENV{qw(IFS CDPATH    ENV BASH_ENV)};      # Make %ENV safer
  252.  
  253.       It's also possible to    get into trouble with other operations
  254.       that don't care whether they use tainted values.  Make
  255.       judicious use    of the file tests in dealing with any user-
  256.       supplied filenames.  When possible, do opens and such    aaaafffftttteeeerrrr
  257.       properly dropping any    special    user (or group!)  privileges.
  258.  
  259.  
  260.  
  261.      Page 4                        (printed 10/23/98)
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  269.  
  270.  
  271.  
  272.       Perl doesn't prevent you from    opening    tainted    filenames for
  273.       reading, so be careful what you print    out.  The tainting
  274.       mechanism is intended    to prevent stupid mistakes, not    to
  275.       remove the need for thought.
  276.  
  277.       Perl does not    call the shell to expand wild cards when you
  278.       pass ssssyyyysssstttteeeemmmm and eeeexxxxeeeecccc explicit    parameter lists    instead    of
  279.       strings with possible    shell wildcards    in them.
  280.       Unfortunately, the ooooppppeeeennnn, gggglllloooobbbb, and backtick functions
  281.       provide no such alternate calling convention,    so more
  282.       subterfuge will be required.
  283.  
  284.       Perl provides    a reasonably safe way to open a    file or    pipe
  285.       from a setuid    or setgid program: just    create a child process
  286.       with reduced privilege who does the dirty work for you.
  287.       First, fork a    child using the    special    ooooppppeeeennnn syntax that
  288.       connects the parent and child    by a pipe.  Now    the child
  289.       resets its ID    set and    any other per-process attributes, like
  290.       environment variables, umasks, current working directories,
  291.       back to the originals    or known safe values.  Then the    child
  292.       process, which no longer has any special permissions,    does
  293.       the ooooppppeeeennnn or other system call.  Finally, the child passes
  294.       the data it managed to access    back to    the parent.  Because
  295.       the file or pipe was opened in the child while running under
  296.       less privilege than the parent, it's not apt to be tricked
  297.       into doing something it shouldn't.
  298.  
  299.       Here's a way to do backticks reasonably safely.  Notice how
  300.       the eeeexxxxeeeecccc is not called with a    string that the    shell could
  301.       expand.  This    is by far the best way to call something that
  302.       might    be subjected to    shell escapes: just never call the
  303.       shell    at all.
  304.  
  305.           use English;
  306.           die "Can't fork: $!" unless defined $pid = open(KID, "-|");
  307.           if ($pid)    {        # parent
  308.           while    (<KID>)    {
  309.               #    do something
  310.           }
  311.           close    KID;
  312.           }    else {
  313.           my @temp = ($EUID, $EGID);
  314.           $EUID    = $UID;
  315.           $EGID    = $GID;       #      initgroups() also called!
  316.           # Make sure privs are    really gone
  317.           ($EUID, $EGID) = @temp;
  318.           die "Can't drop privileges"
  319.               unless $UID == $EUID    && $GID    eq $EGID;
  320.           $ENV{PATH} = "/bin:/usr/bin";
  321.           exec 'myprog', 'arg1', 'arg2'
  322.               or die "can't exec myprog: $!";
  323.           }
  324.  
  325.  
  326.  
  327.      Page 5                        (printed 10/23/98)
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  335.  
  336.  
  337.  
  338.       A similar strategy would work    for wildcard expansion via
  339.       glob,    although you can use readdir instead.
  340.  
  341.       Taint    checking is most useful    when although you trust
  342.       yourself not to have written a program to give away the
  343.       farm,    you don't necessarily trust those who end up using it
  344.       not to try to    trick it into doing something bad.  This is
  345.       the kind of security checking    that's useful for set-id
  346.       programs and programs    launched on someone else's behalf,
  347.       like CGI programs.
  348.  
  349.       This is quite    different, however, from not even trusting the
  350.       writer of the    code not to try    to do something    evil.  That's
  351.       the kind of trust needed when    someone    hands you a program
  352.       you've never seen before and says, "Here, run    this."    For
  353.       that kind of safety, check out the Safe module, included
  354.       standard in the Perl distribution.  This module allows the
  355.       programmer to    set up special compartments in which all
  356.       system operations are    trapped    and namespace access is
  357.       carefully controlled.
  358.  
  359.       SSSSeeeeccccuuuurrrriiiittttyyyy BBBBuuuuggggssss
  360.  
  361.       Beyond the obvious problems that stem    from giving special
  362.       privileges to    systems    as flexible as scripts,    on many
  363.       versions of Unix, set-id scripts are inherently insecure
  364.       right    from the start.     The problem is    a race condition in
  365.       the kernel.  Between the time    the kernel opens the file to
  366.       see which interpreter    to run and when    the (now-set-id)
  367.       interpreter turns around and reopens the file    to interpret
  368.       it, the file in question may have changed, especially    if you
  369.       have symbolic    links on your system.
  370.  
  371.       Fortunately, sometimes this kernel "feature" can be
  372.       disabled.  Unfortunately, there are two ways to disable it.
  373.       The system can simply    outlaw scripts with any    set-id bit
  374.       set, which doesn't help much.     Alternately, it can simply
  375.       ignore the set-id bits on scripts.  If the latter is true,
  376.       Perl can emulate the setuid and setgid mechanism when    it
  377.       notices the otherwise    useless    setuid/gid bits    on Perl
  378.       scripts.  It does this via a special executable called
  379.       ssssuuuuiiiiddddppppeeeerrrrllll that    is automatically invoked for you if it's
  380.       needed.
  381.  
  382.       However, if the kernel set-id    script feature isn't disabled,
  383.       Perl will complain loudly that your set-id script is
  384.       insecure.  You'll need to either disable the kernel set-id
  385.       script feature, or put a C wrapper around the    script.     A C
  386.       wrapper is just a compiled program that does nothing except
  387.       call your Perl program.   Compiled programs are not subject
  388.       to the kernel    bug that plagues set-id    scripts.  Here's a
  389.       simple wrapper, written in C:
  390.  
  391.  
  392.  
  393.      Page 6                        (printed 10/23/98)
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  401.  
  402.  
  403.  
  404.           #define REAL_PATH    "/path/to/script"
  405.           main(ac, av)
  406.           char **av;
  407.           {
  408.           execv(REAL_PATH, av);
  409.           }
  410.  
  411.       Compile this wrapper into a binary executable    and then make
  412.       _i_t rather than your script setuid or setgid.
  413.  
  414.       See the program wwwwrrrraaaappppssssuuuuiiiidddd in the _e_g directory of your Perl
  415.       distribution for a convenient    way to do this automatically
  416.       for all your setuid Perl programs.  It moves setuid scripts
  417.       into files with the same name    plus a leading dot, and    then
  418.       compiles a wrapper like the one above    for each of them.
  419.  
  420.       In recent years, vendors have    begun to supply    systems    free
  421.       of this inherent security bug.  On such systems, when    the
  422.       kernel passes    the name of the    set-id script to open to the
  423.       interpreter, rather than using a pathname subject to
  424.       meddling, it instead passes /_d_e_v/_f_d/_3.  This is a special
  425.       file already opened on the script, so    that there can be no
  426.       race condition for evil scripts to exploit.  On these
  427.       systems, Perl    should be compiled with
  428.       -DSETUID_SCRIPTS_ARE_SECURE_NOW.  The    CCCCoooonnnnffffiiiigggguuuurrrreeee program that
  429.       builds Perl tries to figure this out for itself, so you
  430.       should never have to specify this yourself.  Most modern
  431.       releases of SysVr4 and BSD 4.4 use this approach to avoid
  432.       the kernel race condition.
  433.  
  434.       Prior    to release 5.003 of Perl, a bug    in the code of
  435.       ssssuuuuiiiiddddppppeeeerrrrllll could introduce a security hole in systems compiled
  436.       with strict POSIX compliance.
  437.  
  438.       PPPPrrrrooootttteeeeccccttttiiiinnnngggg YYYYoooouuuurrrr PPPPrrrrooooggggrrrraaaammmmssss
  439.  
  440.       There    are a number of    ways to    hide the source    to your    Perl
  441.       programs, with varying levels    of "security".
  442.  
  443.       First    of all,    however, you _c_a_n'_t take    away read permission,
  444.       because the source code has to be readable in    order to be
  445.       compiled and interpreted.  (That doesn't mean    that a CGI
  446.       script's source is readable by people    on the web, though.)
  447.       So you have to leave the permissions at the socially
  448.       friendly 0755    level.    This lets people on your local system
  449.       only see your    source.
  450.  
  451.       Some people mistakenly regard    this as    a security problem.
  452.       If your program does insecure    things,    and relies on people
  453.       not knowing how to exploit those insecurities, it is not
  454.       secure.  It is often possible    for someone to determine the
  455.       insecure things and exploit them without viewing the source.
  456.  
  457.  
  458.  
  459.      Page 7                        (printed 10/23/98)
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.      PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
  467.  
  468.  
  469.  
  470.       Security through obscurity, the name for hiding your bugs
  471.       instead of fixing them, is little security indeed.
  472.  
  473.       You can try using encryption via source filters (Filter::*
  474.       from CPAN).  But crackers might be able to decrypt it.  You
  475.       can try using    the byte code compiler and interpreter
  476.       described below, but crackers    might be able to de-compile
  477.       it.  You can try using the native-code compiler described
  478.       below, but crackers might be able to disassemble it.    These
  479.       pose varying degrees of difficulty to    people wanting to get
  480.       at your code,    but none can definitively conceal it (this is
  481.       true of every    language, not just Perl).
  482.  
  483.       If you're concerned about people profiting from your code,
  484.       then the bottom line is that nothing but a restrictive
  485.       licence will give you    legal security.     License your software
  486.       and pepper it    with threatening statements like "This is
  487.       unpublished proprietary software of XYZ Corp.     Your access
  488.       to it    does not give you permission to    use it blah blah
  489.       blah."  You should see a lawyer to be    sure your licence's
  490.       wording will stand up    in court.
  491.  
  492.      SSSSEEEEEEEE AAAALLLLSSSSOOOO
  493.       the _p_e_r_l_r_u_n manpage for its description of cleaning up
  494.       environment variables.
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.      Page 8                        (printed 10/23/98)
  526.  
  527.  
  528.  
  529.